package com.smr.micservice.common.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.smr.micservice.common.exception.ParamsValidException;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JsonUtil {

    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    public static final TypeReference<HashMap<String, Object>> HASH_MAP_STRING_OBJECT = new TypeReference<HashMap<String, Object>>() {
    };

    /**
     * 将对象转化为json
     */
    public static String toJson(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (Exception e) {
            throw new ParamsValidException(e.getMessage(), e);
        }
    }

    /**
     * 将json转化为对象
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        if (json == null) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (Exception e) {
            throw new ParamsValidException(e.getMessage(), e);
        }
    }

    /**
     * 将json对象转化为集合类型
     */
    public static <T> Collection<T> fromJson(String json, Class<? extends Collection> collectionClazz, Class<T> clazz) {
        if (json == null) {
            return null;
        }
        try {
            Collection<T> collection = OBJECT_MAPPER.readValue(json, getCollectionType(collectionClazz, clazz));
            return collection;
        } catch (Exception e) {
            throw new ParamsValidException(e.getMessage(), e);
        }
    }

    public static <K, V> Map<K, V> fromJson(String json, TypeReference<HashMap<K, V>> tTypeReference) {
        if (json == null) {
            return null;
        }
        try {
            Map<K, V> map = OBJECT_MAPPER.readValue(json, tTypeReference);
            return map;
        } catch (Exception e) {
            throw new ParamsValidException(e.getMessage(), e);
        }
    }

    private static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }
}
